package bubbleindex;

import java.awt.EventQueue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * 
 * @author ttrott
 */
public class BubbleIndex {
   
    public static String CategoryName = "";
    public static String SelectionName = "";
    public static float Omega;
    public static float M;
    public static float T_crit;
    public static List<Integer> windowLengths;
    public static List<String> DailyPriceDataList;
    public static List<String> DailyPriceDateList;
    public static String PreviousFilePath = "";
    public static String FilePath = "";
    public static String SavePath = "";
    public static float[] DailyPriceValues;
    public static Integer[] BacktestDayLengths;
    public static int ThreadNumber;
    public static boolean isGUI;
    public static boolean forceCPU;
    
    public static void RunBubbleIndex() throws ExecutionException, IOException, InterruptedException {
        
        DailyPriceDataList = new ArrayList<>();
        DailyPriceDateList = new ArrayList<>();
        windowLengths = new ArrayList<>();
       
        setFilePaths();
        displayFilePaths();
        isCPUForced();
        setOmega_M_T();
        setThreads();
        
        InputData.ReadValues(FilePath, DailyPriceDateList, DailyPriceDataList, false, false);

        final int DAILY_DATA_SIZE = DailyPriceDataList.size();

        DailyPriceValues = new float[DAILY_DATA_SIZE];
        ConvertPrices(DailyPriceValues, DAILY_DATA_SIZE);

        final int NUMBER_OF_INDICES = GetDayLengths();
        BacktestDayLengths = new Integer[NUMBER_OF_INDICES];
        BacktestDayLengths = windowLengths.toArray(BacktestDayLengths);
        
        BuildIndex.Create(DAILY_DATA_SIZE, NUMBER_OF_INDICES);

        displayOutput("Done", true);
    }

    private static void setFilePaths() {

        FilePath = Indices.userDir + "ProgramData" + 
                Indices.filePathSymbol + CategoryName + Indices.filePathSymbol +
                SelectionName + Indices.filePathSymbol + SelectionName + 
                "dailydata.csv";

        SavePath = Indices.userDir + "ProgramData" + Indices.filePathSymbol + 
                CategoryName + Indices.filePathSymbol + SelectionName + Indices.filePathSymbol;
    }

    private static void displayFilePaths() { 
        displayOutput("Output File Path: " + FilePath, false);
        displayOutput("Output Save Path: " + SavePath, false);
    }

    private static void setOmega_M_T() {
        if (isGUI) {
            Omega = Float.parseFloat(GUI.OmegaTextField.getText().trim());
            M = Float.parseFloat(GUI.MTextField.getText().trim());
            T_crit = Float.parseFloat(GUI.TCriticalField.getText().trim());
        }
        else {
            Omega = noGUI.omega;
            M = noGUI.m;
            T_crit = noGUI.tCrit;
        }
    }

    public static void setThreads() {
        if (isGUI) {
            ThreadNumber = Integer.parseInt(GUI.ThreadNumber.getText().trim());
        }
        else {
            ThreadNumber = noGUI.threads;
        }
    }
    
    public static void displayOutput(String displayText, boolean resetTextArea) {
        if (isGUI) {
            final String outputString = displayText;
            final boolean reset = resetTextArea;
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() { 
                    if (reset) {
                        GUI.OutputText.setText("");
                    }
                    GUI.OutputText.append(outputString + "\n");
                }
            });
        }
        else {
            System.out.println(displayText);
        }
    }

    private static void isCPUForced() {
        if (isGUI) {
            forceCPU = GUI.forceCPUBox.isSelected();
        }
        else {
            forceCPU = noGUI.forcedCPU;
        }
    }
    
    private static void ConvertPrices(float[] PriceDataArray, final int DAILY_DATA_SIZE) {
        for (int i = 0; i < DAILY_DATA_SIZE; i++) {
            try {                
                PriceDataArray[i] = Float.parseFloat(DailyPriceDataList.get(i));
            } catch (NumberFormatException ex) {
                System.out.println("Number Format Exception. Code 030.");
            }
        }
    }

    private static int GetDayLengths() {
        
        if (BubbleIndex.isGUI) {
            String[] rawFieldData = GUI.windowsTextField.getText().split(",");

            for (String rawFieldData1 : rawFieldData) {
                windowLengths.add(Integer.parseInt(rawFieldData1.trim()));
            }

            return windowLengths.size();
        }
        
        else {
            String[] rawFieldData = noGUI.windows.split(",");

            for (String rawFieldData1 : rawFieldData) {
                windowLengths.add(Integer.parseInt(rawFieldData1.trim()));
            }

            return windowLengths.size();
            
        }
    }
}
